package net.wanho.listener;

import com.rabbitmq.client.Channel;
import net.wanho.po.Student;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Author：汤小洋
 * Date：2024-03-27 11:35
 * Description：<描述>
 */
@Component
public class MsgListener {

    @RabbitListener(queues = "queue1")
    // public void readMsg(String msg){
    public void readMsg(Student stu){
        System.out.println("----------接收到消息："+stu);
    }

    @RabbitListener(queues = "${shop.queue}")
    public void readMsg2(Student stu){
        System.out.println("----------接收到消息2："+stu);
    }

    /**
     * 使用注解指定交换机和队列
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue2"),
            exchange = @Exchange(value = "exchange2.fanout", type = ExchangeTypes.FANOUT)
    ))
    public void readMsg3(Student stu){
        System.out.println("----------接收到消息3："+stu);
    }

    /**
     * 消息可靠性
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue3"),
            exchange = @Exchange(value = "exchange3.direct", type = ExchangeTypes.DIRECT),
            key = "hello"
    ))
    public void readMsg4(String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        System.out.println("----------接收到消息4："+msg);

        // 业务逻辑处理。。。。。

        // 消息处理成功，发送确认消息
        // channel.basicAck(tag, false); // 参数：消息的tag，是否批量确认

        // 消息处理失败，不确认消息
        // channel.basicNack(tag, false, false); // 参数：消息的tag，是否批量确认，是否重新放入队列

        // 拒绝消息
        channel.basicReject(tag, false); // 参数：消息的tag，是否重新放入队列

        /**
         * 如果未确认消息或拒绝消息，且没有重新入队列，消息会被丢弃，变成死信消息
         */
    }


    /**
     * 列信
     */
    @RabbitListener(queues = "normal.queue")
    public void paramMessage(String msg,Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        // try {
        //     Thread.sleep(500);
        // } catch (InterruptedException e) {
        //     throw new RuntimeException(e);
        // }

        // System.out.println("正常：" +  msg);
        // channel.basicAck(tag,false);

        // 模拟：如果是偶数，则业务处理正常，确认消息
        if(Integer.parseInt(msg.substring(2))%2 == 0){
            System.out.println("正常：" +  msg);
            channel.basicAck(tag,false);
        }else{
            // 如果是奇数，则业务处理失败，拒收消息，且不再重新放入队列
            channel.basicNack(tag,false,false);
        }
    }

    @RabbitListener(queues = "dead.queue")
    public void deathMessage(String msg,Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        System.out.println("死信-----：" +  msg);
        channel.basicAck(tag,false);
    }

}
